package multiThreading;

public class SynchronizedDemo
{
  public static void main(String args[])
  {
    Shared target = new Shared();
    Caller ob1 = new Caller(target, "Hello");
    Caller ob2 = new Caller(target, "Synchronized");
    Caller ob3 = new Caller(target, "World3");
    Caller ob4 = new Caller(target, "World4");
    Caller ob5 = new Caller(target, "World5");
    Caller ob6 = new Caller(target, "World6");
    Caller ob7 = new Caller(target, "World7");
    
    // wait for threads to end
    try
    {
      ob1.t.join();
      ob2.t.join();
      ob3.t.join();
    }
    catch (InterruptedException e)
    {
      System.out.println("Interrupted");
    }
  }

  static class Caller implements Runnable
  {
    String msg;

    Shared target;

    Thread t;

    public Caller(Shared targ, String s)
    {
      target = targ;
      msg = s;
      t = new Thread(this);
      t.start();
    }

    // synchronize calls to call()
    public void run()
    {
      //synchronized (target)
      { // synchronized block
        target.call(msg);
      }
    }
  }

  static class Shared
  {
    void call2(String msg)
    {
      synchronized(this)
      {
        
      }
    }
    
    synchronized void call(String msg)
    {
      System.out.print("[" + msg);
      try
      {
        Thread.sleep(1000);
      }
      catch (InterruptedException e)
      {
        System.out.println("Interrupted");
      }
      System.out.println("]");
    }
  }
}
